English version Spanish version German version

Sessione 7: Formulazione di Modelli in MPL con Dati Sparsi

Spesso, quando si lavora con grandi modelli, i dati di quest'ultimi tendono a non essere densi; come nel modello precedente, su cui abbiamo lavorato, e molto più spesso in una disposizione sparsa. I dati densi possono essere percepiti alla stessa maniera dei dati di un foglio elettronico. Normalmente, viene usato per vettori di dati con non più di due dimensioni, dove ogni colonna ed ogni riga è riempita da dati.

I dati sparsi, d'altra parte, coinvolgono tipicamente dimensioni multiple, ma non neccessariamente contengono valori per ogni combinazione di indici. Dati sparsi sono solitamente immagazzinati in un formato di tabella, dove ogni colonna rappresenta un indice o un valore di dati. Quando si lavora con ampie serie di dati sparsi, è comune lavorare con i dati in un format di tabella. Questo vi permette di saltare facilmente certe combinazioni dell'indice, che non sono valide, omettendole nella tabella.

Nuovi Concetti in questa Sessione

Indici di Apparecchiature

A volte, quando formulate modelli di produzione di progettazione, la decisione coinvolge le macchine da usare per produrre i prodotti. Dato che non tutte le macchine sono disponibili in ogni impianto questo introduce una sparsità nel modello. Quando definiamo i dati e i vettori di variabili per il modello, utilizzeremo, dunque, quella sparsità per essere sicuri che la misura del modello non diventi troppo grande. Questo può essere ottenuto sia usando il comando standard WHERE (DOVE) in un vettore di dati, o usando l'operatore IN per connettere gli indici in questione.

L'uso dell' Operatore IN

L'operatore IN in MPL vi permette di selezionare uno degli indici di dominio da un indice multidimensionale. Per esempio, se avete un indice multidimensionale che specifica quali macchine sono disponibili in quali impianti, potete usare l'operatore IN per sommare l'eccedenza di tutte le macchine per quel particolare impianto.

     INDEX
        plant     := (p1, p2, p3, p4);
        machine   := (m11, m12, m13, m21, m22, m31, m32, m41);

        PlantMach[plant,machine]  :=

             (p1.m11, p1.m12, p1.m13,
              p2.m21, p2.m22,
              p3.m31, p3.m32,
              p4.m41);
    

Nell'esempio qui sopra, abbiamo definito un indice multidimensionale chiamato PlantMach che connette gli impianti alle macchine corrispondenti.

L'indice PlantMach può, dunque, essere usato, in maniera selettiva, per scegliere solo le macchine che sono disponibili in un impianto particolare. Per esempio:

     SUBJECT TO
        PlantCapacity[plant] :
           SUM(machine IN PlantMach: Produce[machine])  <=  MaxCapacity[plant];
    

Nell'esempio qui sopra, sommiamo quanto viene prodotto in ogni macchina in quel particolare impianto. Così ci assicuriamo che la produzione totale sia circoscritta alla capacità massima.

Files d'Indice

Così come potete accumulare i dati in files esterni di dati, potete anche conservare gli indici in files esterni d'indici. Files d'indice vi permettono di conservare gli elementi in un file d'indice invece di specificarli direttamente nel modello. Quando si sta definendo un indice con un file d'indice si usi la parola chiave INDEXFILE con un nome di file invece della solita lista di elementi. Per esempio:

     INDEX
        product    := INDEXFILE("Product.idx");
        month      := INDEXFILE("Month.idx");
        plant      := INDEXFILE("Plant.idx");
    

Il file d'indice è un file di testo standard contenente una lista di elementi d'indice per l'indice particolare. Potete separare gli elementi nel file sia con una virgola, sia con uno spazio o con entrambi. Ad esempio, troverete, qui, un file d'indice campione per l'indice product (prodotto):

     !  Product.idx  -  Index element for the product index

         A1, A2, A3
    

Files di Dati Sparsi

Generalmente, quando si lavora con modelli sparsi, il dato cinvolto è abbastanza grande e proviene da altre applicazioni, come database comuni o desktop. Nella Sessione precedente, il dato veniva inserito nel file di modello o conservato in un file di dati denso. Quando si lavora con grandi insiemi di dati, si ha bisogno di un metodo più efficiente per importare i dati in MPL da altre applicazioni. Per questo motivo MPLpossiede la capacità di leggere i dati da un file sparso di dati. Questo file vi permette di introdurre i dati in unformato di lista standard, che è più vicino alle attuali caratteristiche dei dati, per esempio, da un database relazionale. Un esempio di file di dati sparso può essere il seguente:

        ProdCost[plant, machine, product]  := SPARSEFILE("ProdCost.dat");
    

Il file ProdCost.dat contiene i dati in una disposizione orientata a colonna con gli indici elencati nelle prime tre colonne e il corrispondente valore di dati alla fine di ogni linea come di seguito:

              p1,  m11,  A1,  73.30,
              p1,  m11,  A2,  52.90,
              p1,  m12,  A3,  65.40,
                    .
                    .
                    .
              p4,  m41,  A2,  63.30,
              p4,  m41,  A3,  53.80
    

Per favore si noti che, MPL vi permette, inoltre, di conservare colonne multiple di dati in un singolo file di dati sparsi. Si specifichi quali colonne aggiungendo una virgola e il numero della colonna di dati dopo il nome del file dentro le parentesi.

       ProdCost[plant, machine, product]  := SPARSEFILE("ProdCost.dat", 2);
    

L'uso di file di dati sparsi è comune nella reale modellazione. Questi file possono finire per essere abbastanza grandi, con indici multipli e contenere molti dati. Di frequente, potrete avere files d'indice multiplo e files di dati sparsi che contengono tutti i dati e lasciano il file di modello solo per contenere le dichiarazioni del modello attuale, come le variabili, la funzione obiettivo e i limiti.


Descrizione del Problema: Un Modello di Pianificazione con Macchine Multiple per Ogni Impianto

In questa sessione, aggiornerete il modello così d'avere macchine multiple distribuite tra gli impianti. Userete il modello creato nella sessione 6, farete le necessarie aggiunte e aggiornamenti.

Dato che abbiamo macchine diverse in ogni impianto, il costo di produzione e il tasso di produzione ora hanno valori diversi per ogni macchina. La tabella seguente mostra una linea singola per ogni impainto, macchina, combinazione di prodotto che è applicabile.

La decisione della produzione, quanto volgiamo produrre per ogni prdotto, deve tener conto che ora abbiamo molteplici macchine. Perciò, aggiornerete la variabile Produce così da includere l'indice machine e poi usare la condizione WHERE per escludere gli elementi non applicabili, come l'impianto p1, la macchina m11, e il prodotto A3.


Formulazione del Modello in MPL

Elencata qui sotto, troverete l'intera formulazione del modello per il Planning7. Le aggiunte al modello sono evidenziate in neretto per rendervi più facilmente visibili i cambiamenti al modello della Sessione 6.

     TITLE
         Production_Planning7;

     INDEX
         product    :=  (A1, A2, A3);
         month      :=  (Jan, Feb, Mar, Apr);
         plant      :=  (p1, p2, p3, p4);
         toplant    :=  plant;
         fromplant  :=  plant;
         machine    :=  (m11, m12, m13, m21, m22, m31, m32, m41);

     DATA
         Price[product]                     :=  (120.00, 100.00, 115.00);
         Demand[plant, product, month]      :=  DATAFILE("Demand6.dat");
         ProdCost[plant, machine, product]  :=  SPARSEFILE("Produce.dat", 1);
         ProdRate[plant, machine, product]  :=  SPARSEFILE("Produce.dat", 2);

         ProdDaysAvail[month]               :=  (23, 20, 23, 22);
         InvtCost[plant, product]           :=  DATAFILE("InvtCost.dat");
         InvtCapacity[plant]                :=  (800, 400, 500, 400);
         ShipCost[fromplant, toplant]       :=  DATAFILE ("ShipCost.dat");

     VARIABLES
         Produce[plant, machine, product, month] -> Prod
             WHERE (ProdCost > 0);
         Inventory[plant, product, month]        -> Invt;
         Sales[plant, product, month]            -> Sale;
         Ship[product, month, fromplant, toplant]
             WHERE (fromplant <> toplant);

     MACROS
         TotalRevenue  := SUM(plant, product, month: Price * Sales);
         TotalProdCost := SUM(plant, machine, product,month: ProdCost * Produce);
         TotalInvtCost := SUM(plant, product, month: InvtCost * Inventory);
         TotalShipCost := SUM(product, month, fromplant, toplant: ShipCost * Ship);
         TotalCost     := TotalProdCost + TotalInvtCost + TotalShipCost;

     MODEL

         MAX Profit  =  TotalRevenue - TotalCost;

     SUBJECT TO
         ProdCapacity[plant, machine, month] -> PCap:
             SUM(product: Produce / ProdRate)  <=  ProdDaysAvail;

         PlantBal[plant, product, month] -> PBal:
               SUM(machine: Produce) + Inventory[month-1]
             + SUM(fromplant: Ship[fromplant, toplant:=plant])
           =
               Sales + Inventory
             + SUM(toplant: Ship[fromplant:=plant, toplant]);

         MaxInventory[plant, month] -> MaxI:
            SUM(product: Inventory)  <=  InvtCapacity;

     BOUNDS
        Sales  <  Demand;

     END
   

Introdurre Nuovi Elementi al Modello Passo per Passo

Passo 1: Eseguire MPL e Creare un Nuovo Modello

  1. Eseguire l'applicazione MPL.

  2. Scegliere File(Archivio) | Open(Aprire) e aprire il modello dalla sessione precedente Planning6.mpl.

  3. Scegliere File(Archivio) | Save As (Salva come) per salvarlo come un nuovo file di modello Planning7.mpl.

Passo 2: Cambiare il Titolo al Modello

Cambiare il Titolo al Modello per sottolineare che state lavorando con il modello Planning7.

     TITLE
         Production_Planning7;
    

Passo 3: Agiungere l'Indice 'machine' al Modello

In questo modello, ogni impianto ha, ora, molteplici macchine. Per creare un indice per le macchine aggiungere la seguente definizione per l'indice machine nella sezione INDEX.

     INDEX
         product   :=  (A1, A2, A3);
         month     :=  (Jan, Feb, Mar, Apr);
         plant     :=  (p1, p2, p3, p4);
         toplant   :=  plant;
         fromplant :=  plant;
         machine   :=  (m11, m12, m13, m21, m22, m31, m32, m41);
     

Passo 4: Aggiornare i Vettori di Dati 'ProdCost' e 'ProdRate' per Includere l'Indice 'machine'

Il costo di produzione e il tasso di produzione ora hanno bisogno d'includere l'indice della macchina dato che abbiamo valori di dati diversi per ogni macchina.Inoltre, visto che il dato è ora sparso, cioè non tutti gli impianti hanno tutte la macchine, accumulerete i dati in un file di dati sparsi. MPL permette di accumulare colonne di molteplici dati in un singolo file di dati sparsi. Specificate quale colonna leggre aggiungendo una virgola e il numero della colonna di dati dopo il nome del file.

Aggiornare le definizioni per i vettori di dati ProdCost e ProdRate per includere l'indice machine e cambiare i nomi del file in un nuovo file di dato sparso chiamato Produce.dat. Per il costo di produzione specificare il numero della colonna 1 dopo il nome del file e per il tasso di produzione specificare il numero della colonna 2.

     DATA
         Price[product]                     :=  (120.00, 100.00, 115.00);
         Demand[plant, product, month]      :=  DATAFILE("Demand6.dat");
         ProdCost[plant, machine, product]  :=  SPARSEFILE("Produce.dat", 1);
         ProdRate[plant, machine, product]  :=  SPARSEFILE("Produce.dat", 2);
         ProdDaysAvail[month]               :=  (23, 20, 23, 22);
         InvtCost[product]                  :=  DATAFILE("InvtCost.dat");
         InvtCapacity[plant]                :=  (800, 400, 500, 400);
         ShipCost[fromplant, toplant]       :=  DATAFILE("ShipCost.dat");
    

Passo 5: Creare un file di Dati Sparsi per il Costo di Produzione e il Tasso di Produzione

Ora avete bisogno di creare il file di dati sparsi Produce.dat dai dati forniti nella descrizione del problema precedentemente in questa sessione.

Per creare i file di dati per il costo di produzione, aprire una nuova finestra di editor per il file di dati, chiamata Produce.dat e inserire quello che segue:

     !
     !  Produce.dat  -  Production Cost and Rate
     !
     !  ProdCost[plant, machine, product]:
     !  ProdRate[plant, machine, product]:
     !

               p1,  m11,  A1,  73.30,  500,
               p1,  m11,  A2,  52.90,  450,
               p1,  m12,  A3,  65.40,  550,
               p1,  m13,  A3,  47.60,  350,

               p2,  m21,  A1,  79.00,  550,
               p2,  m21,  A3,  66.80,  450,
               p2,  m22,  A2,  52.00,  300,

               p3,  m31,  A1,  75.80,  450,
               p3,  m31,  A3,  50.90,  300,
               p3,  m32,  A1,  79.90,  400,
               p3,  m32,  A2,  52.10,  350,

               p4,  m41,  A1,  82.70,  550,
               p4,  m41,  A2,  63.30,  400,
               p4,  m41,  A3,  53.80,  350,
     

Passo 6: Aggiornare il Vettore della Variabile di Produzione per includere l'Indice 'machine'

La variabile Produce necessita ora di avere l'indice machine nelle dichiarazioni come noi abbiamo bisogno di sapere su quale macchina ogni prodotto viene realizzato.Inoltre, dato che non tutte le macchine sono in ogni impianto, abbiamo bisogno di escludere le combinazioni dell'indice non valide. Questo viene fatto usando la condizione where sul vettore di dati ProdCost. Le combinazioni di indici sono usate solo quando ProdCost è maggiore di zero o quando si allarga la variabile Produce. Introdurre i cambiamenti alla variabile Produce come segue:

     VARIABLES
         Produce[plant, machine, product, month] -> Prod
             WHERE (ProdCost > 0);
    

Passo 7: Aggiungere l'indice 'machine' alla Macro for per il Costo della Produzione Totale

Nella macro, per il costo totale di produzione, aggiungere l'indice machine per sottolineare che la variabile Produce ora contiene l'indice machine.

     MACROS
         TotalRevenue  := SUM(plant, product, month: Price * Sales);
         TotalProdCost := SUM(plant, machine, product,month: ProdCost * Produce);
         TotalInvtCost := SUM(plant, product, month: InvtCost * Inventory);
         TotalShipCost := SUM(product, month, fromplant,toplant: ShipCost * Ship);
         TotalCost     := TotalProdCost + TotalInvtCost + TotalShipCost;
    

Passo 8: Aggiornare il Vincolo 'ProdCapacity' per includere l'Indice 'machine'

Nella dichiarazione per il vincolo della capacità di produzione, l'indice machine deve essere incluso dato che ora abbiamo separato il limite della capacità per ogni macchina nell'impianto. Introdurre i cambiamenti al vincolo ProdCapacity come segue:

     SUBJECT TO
        ProdCapacity[plant, machine, month] -> PCap:
            SUM(product: Produce / ProdRate)  <=  ProdDaysAvail;
    

Passo 9: Aggiornare il Vincolo dell'Equilibrio dell'Impianto per Sommare la Variabile del Prodotto su Tutte le Macchine

Nel vincolo dell'equilibrio dell'impianto abbiamo ora una variabile separata Produce per ogni macchina. Dato che dobbiamo sommare insieme la produzione totale per l'impianto particolare, abbiamo bisogno di sommare sull'indice della macchina quando facciamo riferimento alla variabile Produce. Per far questo aggiungere la sommatoria seguente al vincolo PlantBal:

     PlantBal[plant, product, month] -> PBal:
           SUM(machine: Produce) + Inventory[month-1]
         + SUM(fromplant:  Ship[fromplant, toplant:=plant])
       =
           Sales + Inventory
         + SUM(toplant:  Ship[fromplant:=plant, toplant]);
    

Risolvere il Modello e Analizzare la Soluzione

Il prossimo passo sarà la risoluzione del modello 'Planning7.mpl' scegliendo Solve CPLEX dal menu Run. Se tutto procede bene MPL visualizzerà il messaggio 'Optimal Solution Found' (Trovata Soluzione Ottimale) . Se c'è una finestra con un messaggio d'errore con un errore di sintassi, per favore si controlli la formulazione inserita con il modello descritto precedentemente in questa sessione.

Userete la finestra delle definizioni del modello ancora, come nella Sessione6, per guardare le parti della soluzione che ci interessano. Per aprire le la finestra di definizioni del modello per il modello Planning7scegliere Model Definitions dal menu View.

La finestra del modello dell'abero di definizioni per il modelloPlanning7

Guardando i valori per la variabileProduce (Prodotto) fate doppio click sull'icona del prodotto dell'albero della variabile o selezionatelo e premete il bottone View (Vista). Questo visualizzerà una finestra di visuale contenente i valori della soluzione solo per la variabile Produce che sono mostrati di seguito:

     VARIABLE Produce[plant,machine,product,month] :

   plant  machine  product  month           Activity     Reduced Cost
  --------------------------------------------------------------------
   p1     m11      A1       Jan           4300.0000           0.0000
   p1     m11      A1       Feb           4200.0000           0.0000
   p1     m11      A1       Mar           5487.5000           0.0000
   p1     m11      A1       Apr           5300.0000           0.0000
   p1     m11      A2       Jan           6480.0000           0.0000
   p1     m11      A2       Feb           5220.0000           0.0000
   p1     m11      A2       Mar           5411.2500           0.0000
   p1     m11      A2       Apr           5130.0000           0.0000
   p1     m12      A3       Feb           9049.3506           0.0000
   p1     m12      A3       Mar            916.1616           0.0000
   p1     m12      A3       Apr          10803.1169           0.0000
   p1     m13      A3       Jan           8050.0000           0.0000
   p1     m13      A3       Feb           7000.0000           0.0000
   p1     m13      A3       Mar           8050.0000           0.0000
   p1     m13      A3       Apr           7700.0000           0.0000
   p2     m21      A1       Jan           5100.0000           0.0000
   p2     m21      A1       Feb           6200.0000           0.0000
   p2     m21      A1       Mar           6538.8889           0.0000
   p2     m21      A1       Apr           7600.0000           0.0000
   p2     m21      A3       Jan           4422.6136           0.0000
   p2     m21      A3       Feb           3927.2727           0.0000
   p2     m21      A3       Mar           5000.0000           0.0000
   p2     m21      A3       Apr           3681.8182           0.0000
   p2     m22      A2       Jan           6900.0000           0.0000
   p2     m22      A2       Feb           6000.0000           0.0000
   p2     m22      A2       Mar           6900.0000           0.0000
   p2     m22      A2       Apr           6600.0000           0.0000
   p3     m31      A1       Jan           3300.0000           0.0000
   p3     m31      A1       Feb           5964.9351           0.0000
   p3     m31      A1       Mar           2550.0000           0.0000
   p3     m31      A1       Apr           4477.4026           0.0000
   p3     m31      A3       Jan           4700.0000           0.0000
   p3     m31      A3       Feb           2023.3766           0.0000
   p3     m31      A3       Mar           5200.0000           0.0000
   p3     m31      A3       Apr           3615.0649           0.0000
   p3     m32      A1       Jan            800.0000           0.0000
   p3     m32      A1       Feb            135.0649           0.0000
   p3     m32      A1       Mar           2150.0000           0.0000
   p3     m32      A1       Apr           1322.5974           0.0000
   p3     m32      A2       Jan           7350.0000           0.0000
   p3     m32      A2       Feb           6881.8182           0.0000
   p3     m32      A2       Mar           6168.7500           0.0000
   p3     m32      A2       Apr           6542.7273           0.0000
   p4     m41      A1       Jan           4300.0000           0.0000
   p4     m41      A1       Feb           4100.0000           0.0000
   p4     m41      A1       Mar           5073.6111           0.0000
   p4     m41      A1       Apr           4500.0000           0.0000
   p4     m41      A2       Jan           2270.0000           0.0000
   p4     m41      A2       Feb           5018.1818           0.0000
   p4     m41      A2       Mar           2500.0000           0.0000
   p4     m41      A2       Apr           5527.2727           0.0000
   p4     m41      A3       Jan           3327.3864           0.0000
   p4     m41      A3       Mar           2633.8384           0.0000
  --------------------------------------------------------------------
 

La variabile Produce è ora definita su quattro indici: plant (impianto), machine(macchina), product(prodotto) e month(mese).Per ogni impianto il modello decide quale macchina è la più efficiente per produrre i prodotti in quel particolare impianto. Questa tabella può essere usata come base per un programma di produzione per l'intera compagnia.

L'altra variabile che è coinvolta nel modello è la variabile Inventory (Inventario). Se date un altro sguardo alla finestra ad albero e aprite una finestra di visuale per la variabile Inventory(Inventario) avrete i seguenti valori di soluzione:

     VARIABLE Inventory[plant,product,month] :

        plant  product  month           Activity     Reduced Cost
       -----------------------------------------------------------
        p1     A2       Jan            800.0000           0.0000
        p2     A2       Jan            400.0000           0.0000
        p3     A3       Jan            500.0000           0.0000
        p4     A3       Jan            400.0000           0.0000
       -----------------------------------------------------------
    

Come potete vedere il modello ha deciso di produrre i prodotti A2 e A3 durante Gennaio per essere sicuri di avere abbastanza tra le mani per Febbraio.

La maggior parte degli impianti stanno ora lavorando a pueno ritmo. Se date ancora uno sguardo alla finestra ad albero e aprite una finestra di visuale per il vincolo ProdCapacity avrete i seguenti valori di soluzione:

     CONSTRAINT ProdCapacity[plant,machine,month] :

        plant  machine  month              Slack     Shadow Price
       -----------------------------------------------------------
        p1     m12      Jan             23.0000           0.0000
        p1     m12      Feb              3.9595           0.0000
        p1     m12      Mar             20.2682           0.0000
        p1     m12      Apr              1.2033           0.0000
        p2     m21      Jan              3.6947           0.0000
       -----------------------------------------------------------
    

Come potete vedere l'impianto p1 possiede capacità extra per la macchina m12 e l'impianto p2 possiede capacità extra per la macchina m21. A parte tutto, tutte le macchine in ogni impianto lavorano a pieno ritmo per esaudire la richiesta.


Back To Top | Maximal Home Page | Overview | Previous Page | Next Page